package com.management.department.teacherinfosystem.Controller;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.management.department.teacherinfosystem.Entity.PartyActivity;
import com.management.department.teacherinfosystem.Entity.PartyActivityAttachment;
import com.management.department.teacherinfosystem.Entity.PartyActivityAttendance;
import com.management.department.teacherinfosystem.Entity.User;
import com.management.department.teacherinfosystem.Repository.PartyActivityAttachmentRepository;
import com.management.department.teacherinfosystem.Repository.PartyActivityAttendanceRepository;
import com.management.department.teacherinfosystem.Repository.PartyActivityRepository;
import com.management.department.teacherinfosystem.Repository.UserRepository;

@RestController
@RequestMapping("/api/party")
@CrossOrigin(origins = "*")
public class PartyActivityController {

	@Autowired private PartyActivityRepository activityRepository;
	@Autowired private PartyActivityAttendanceRepository attendanceRepository;
	@Autowired private PartyActivityAttachmentRepository attachmentRepository;
	@Autowired private UserRepository userRepository;

	// ============ Activity CRUD ============
	@PostMapping("/activities")
	@Transactional
	public ResponseEntity<?> createActivity(@RequestBody Map<String, Object> payload) {
		User currentUser = currentUser();
		if (currentUser == null) return ResponseEntity.status(401).body("未登录");
		PartyActivity a = new PartyActivity();
		a.setActivityType((String) payload.get("activity_type"));
		a.setActivitySubject((String) payload.get("activity_subject"));
		a.setLocation((String) payload.get("location"));
		a.setHostName((String) payload.get("host_name"));
		a.setCreatedBy(currentUser.getId());
		a.setParticipantCount((Integer) asNumber(payload.get("participant_count")));
		a.setAbsenceNotes((String) payload.get("absence_notes"));
		a.setActivityRecord((String) payload.get("activity_record"));
		Object hostUserId = payload.get("host_user_id");
		if (hostUserId != null) a.setHostUserId(Long.valueOf(String.valueOf(hostUserId)));
		Date date = parseDate(payload.get("activity_date"));
		if (date != null) a.setActivityDate(date);
		activityRepository.save(a);
		return ResponseEntity.ok(Map.of("id", a.getId()));
	}

    @GetMapping("/activities")
    @Transactional(readOnly = true)
    public List<PartyActivity> listActivities(
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate,
            @RequestParam(value = "status", required = false) String status
    ) {
        if (status != null && !status.isBlank()) {
            return activityRepository.findByStatus(status);
        }
        Date start = parseDate(startDate);
        Date end = parseDate(endDate);
        if (type == null || type.isBlank()) type = null;
        return activityRepository.search(type, start, end);
    }

	@GetMapping("/activities/{id}")
	@Transactional(readOnly = true)
	public ResponseEntity<?> getActivity(@PathVariable("id") Long id) {
		PartyActivity a = activityRepository.findById(id).orElse(null);
		if (a == null) return ResponseEntity.notFound().build();
		Map<String,Object> m = new HashMap<>();
		m.put("activity", a);
		List<PartyActivityAttachment> att = attachmentRepository.findByActivityId(id);
		m.put("attachments", att);
		List<PartyActivityAttendance> atts = attendanceRepository.findByActivityId(id);
		m.put("attendance", atts);
		return ResponseEntity.ok(m);
	}

	@PutMapping("/activities/{id}")
	@Transactional
	public ResponseEntity<?> updateActivity(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
		PartyActivity a = activityRepository.findById(id).orElse(null);
		if (a == null) return ResponseEntity.notFound().build();
        User current = currentUser();
        boolean isAdmin = current != null && current.getUserRoles().stream().anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
        if (current == null || (!isAdmin && !Objects.equals(a.getCreatedBy(), current.getId()))) {
            return ResponseEntity.status(403).body("无权修改");
        }
        a.setActivityType((String) payload.getOrDefault("activity_type", a.getActivityType()));
        a.setActivitySubject((String) payload.getOrDefault("activity_subject", a.getActivitySubject()));
        a.setLocation((String) payload.getOrDefault("location", a.getLocation()));
        a.setHostName((String) payload.getOrDefault("host_name", a.getHostName()));
		Object hostUserId = payload.get("host_user_id");
		if (hostUserId != null) a.setHostUserId(Long.valueOf(String.valueOf(hostUserId)));
		Object pc = payload.get("participant_count");
		if (pc != null) a.setParticipantCount(((Number) asNumber(pc)).intValue());
		a.setAbsenceNotes((String) payload.getOrDefault("absence_notes", a.getAbsenceNotes()));
		a.setActivityRecord((String) payload.getOrDefault("activity_record", a.getActivityRecord()));
		Date date = parseDate(payload.get("activity_date"));
		if (date != null) a.setActivityDate(date);
        // 修改后回到待审核，清空审核信息
        a.setStatus("PENDING");
        a.setReviewOpinion(null);
        a.setReviewerId(null);
        a.setReviewTime(null);
		activityRepository.save(a);
		return ResponseEntity.ok().build();
	}

	@DeleteMapping("/activities/{id}")
	@Transactional
	public ResponseEntity<?> deleteActivity(@PathVariable("id") Long id) {
		if (!activityRepository.existsById(id)) return ResponseEntity.notFound().build();
		attachmentRepository.findByActivityId(id).forEach(att -> attachmentRepository.deleteById(att.getId()));
		attendanceRepository.findByActivityId(id).forEach(at -> attendanceRepository.deleteById(at.getId()));
		activityRepository.deleteById(id);
		return ResponseEntity.ok().build();
	}

	// ============ Attendance ============
	    @PostMapping("/activities/{id}/attendance")
	    @Transactional
	    public ResponseEntity<?> upsertAttendance(@PathVariable("id") Long id, @RequestBody Map<String,Object> payload) {
        User current = currentUser();
        if (current == null) return ResponseEntity.status(401).body("未登录");
        Long userId = payload.get("user_id") != null ? Long.valueOf(String.valueOf(payload.get("user_id"))) : current.getId();
        String status = (String) payload.getOrDefault("attendance_status", "出席");
        String role = (String) payload.getOrDefault("role", null);
        String reason = (String) payload.getOrDefault("reason", null);
        PartyActivityAttendance rec = attendanceRepository.findByActivityIdAndUserId(id, userId);
        if (rec == null) rec = new PartyActivityAttendance();
        rec.setActivityId(id);
        rec.setUserId(userId);
        rec.setAttendanceStatus(status);
        rec.setRole(role);
        rec.setReason(reason);
        attendanceRepository.save(rec);
        return ResponseEntity.ok().build();
    }

	// ============ Attachments ============
	@PostMapping("/activities/{id}/attachments")
	@Transactional
	public ResponseEntity<?> uploadAttachment(@PathVariable("id") Long id, @RequestPart("file") MultipartFile file) throws Exception {
		PartyActivity a = activityRepository.findById(id).orElse(null);
		if (a == null) return ResponseEntity.notFound().build();
		File dir = ensureDir("/uploads/party/");
		String original = Objects.requireNonNull(file.getOriginalFilename());
		String ext = original.contains(".") ? original.substring(original.lastIndexOf('.')) : "";
		String save = System.currentTimeMillis() + "_" + UUID.randomUUID() + ext;
		File dest = new File(dir, save);
		file.transferTo(dest);
		PartyActivityAttachment att = new PartyActivityAttachment();
		att.setActivityId(id);
		att.setFileName(original);
		att.setFileUrl(dir.getPath().replace("\\","/") + "/" + save);
		attachmentRepository.save(att);
		return ResponseEntity.ok(Map.of("url", att.getFileUrl()));
	}

	// ============ Review (Admin) ============
	@PostMapping("/activities/{id}/review")
	@Transactional
	public ResponseEntity<?> reviewActivity(@PathVariable("id") Long id, @RequestBody Map<String,Object> payload) {
		User current = currentUser();
		if (current == null) return ResponseEntity.status(401).body("未登录");
		boolean isAdmin = current.getUserRoles().stream().anyMatch(ur -> ur.getRole() != null && "admin".equalsIgnoreCase(ur.getRole().getName()));
		if (!isAdmin) return ResponseEntity.status(403).body("权限不足");
		PartyActivity a = activityRepository.findById(id).orElse(null);
		if (a == null) return ResponseEntity.notFound().build();
		String s = String.valueOf(payload.get("status"));
		if (!"APPROVED".equals(s) && !"REJECTED".equals(s)) return ResponseEntity.badRequest().body("状态无效");
		a.setStatus(s);
		a.setReviewOpinion((String) payload.get("opinion"));
		a.setReviewerId(current.getId());
		a.setReviewTime(new java.util.Date());
		activityRepository.save(a);
		return ResponseEntity.ok().build();
	}

	@GetMapping("/activities/{id}/attachments")
	@Transactional(readOnly = true)
	public List<PartyActivityAttachment> listAttachments(@PathVariable("id") Long id) {
		return attachmentRepository.findByActivityId(id);
	}

	// ============ Helpers ============
	private File ensureDir(String base) {
		File d = new File(base.endsWith("/") || base.endsWith("\\") ? base : base + File.separator);
		if (!d.exists()) d.mkdirs();
		return d;
	}

	private Date parseDate(Object obj) {
		if (obj == null) return null;
		try { return new SimpleDateFormat("yyyy-MM-dd").parse(String.valueOf(obj)); } catch (Exception e) { return null; }
	}
	private Number asNumber(Object v) { return v == null ? null : (v instanceof Number ? (Number) v : Double.valueOf(String.valueOf(v))); }
	private User currentUser() {
		org.springframework.security.core.Authentication auth =
				org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
		String currentUsername = auth == null ? null : auth.getName();
		return currentUsername == null ? null : userRepository.findByUsernameWithRoles(currentUsername).orElse(null);
	}
} 